Skip to content

refactor(security): 移除 JWT 依赖,简化为 API Key + Bot ID 认证 (#467)#476

Merged
hrygo merged 3 commits into
mainfrom
refactor/467-remove-jwt-dependency
May 22, 2026
Merged

refactor(security): 移除 JWT 依赖,简化为 API Key + Bot ID 认证 (#467)#476
hrygo merged 3 commits into
mainfrom
refactor/467-remove-jwt-dependency

Conversation

@hrygo
Copy link
Copy Markdown
Owner

@hrygo hrygo commented May 22, 2026

Resolves #467

Summary

  • 移除 ES256 JWT 签名认证体系(jwt.go、HKDF 密钥派生、JTI 黑名单),替换为 X-API-Key + X-Bot-ID 双头认证模型
  • 简化 config.Load() 接口,删除 LoadOptions/SecretsProvider 管线
  • 更新所有 SDK(Go/Java/TypeScript/Python)示例和文档,移除 JWT 相关代码

Breaking Changes

移除项 替代方案
internal/security/jwt.go API Key 认证 (X-API-Key header)
client/token.go (token 生成) X-Bot-ID header
config.LoadOptions / SecretsProvider config.Load(path) 单参数
BotIDFromHeader BotIDFromRequest
Java JwtTokenGenerator + jjwt/bcprov X-Bot-ID header
TS generate-test-token.ts AEP init envelope auth.token

Migration Guide

  1. 设置 HOTPLEX_ADMIN_TOKEN_1 环境变量(替代 JWT signing key)
  2. HTTP 客户端:使用 X-API-Key + X-Bot-ID header
  3. WebSocket 客户端:通过 AEP init envelope 的 auth.token + auth.bot_id 传递凭证
  4. 删除所有 JWT signing key 相关配置

Stats

124 files changed, +857 / -3,815 lines

Test plan

  • go test ./... -short 全绿
  • Java mvn compile 通过
  • TypeScript tsc --noEmit 通过
  • Python py_compile 通过
  • 40+ 文档文件 JWT 防腐验证
  • Pre-commit hooks (gofmt + golangci-lint + go vet + build + test) 全通过

hotplex-ai
hotplex-ai previously approved these changes May 22, 2026
Copy link
Copy Markdown
Owner

@hotplex-ai hotplex-ai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #476 审查报告 — hotplex-ai 三维度自动审查

裁决: APPROVE (有 WARN 项,附后供参考)

代码质量: PASS

  • DRY/SOLID/命名/错误处理/风格均通过
  • 净删除 ~2000+ 行,跨语言 JWT 重复代码消除
  • WARN: docs/guides/enterprise/security-hardening.md items 3&4 语义重复

非功能性: WARN

  • 性能: PASS — 移除 JTI sweep goroutine、HKDF、ECDSA 验证,API Key map 查找 O(1)
  • 安全: WARN
    • 认证模型从 ES256 JWT 降级为明文 API Key,丢失 token 过期/撤销/签名验证/权限粒度
    • API Key 比较未使用 subtle.ConstantTimeCompare(map lookup,注释已说明可接受性)
    • Dev mode 无 Key 配置时静默放行,建议非 localhost 绑定时输出 WARN 日志
    • 浏览器 WebSocket init envelope 明文传输 API Key,文档需强调生产环境 WSS
    • api_key_strength checker 替代已移除的 jwt_strength checker
  • 并发: PASS — 移除 JTI blacklist sync.Map + sweep goroutine,RWMutex copy-on-write 模式正确

集成与防腐: WARN

  • 文档: PASS — 40+ 文档全部同步,CHANGELOG 迁移指南完整
  • 测试: PASS — JWT 测试正确清理,新认证路径测试充分
  • API 兼容性: FAIL(有意为之) — 10+ Breaking Change(config.Load/NewWatcher/NewAuthenticator 签名变更、SDK API 变更),均有迁移指南覆盖
  • 依赖: PASS — 仅移除 JWT 相关依赖(Go/Java/TS),无新增
  • 变更范围: WARN
    • QuickStart.java 变量名 signingKey 应改为 apiKey
    • PII 检测列表移除 eyJ... JWT 模式
    • docs/guides/enterprise/integration-patterns.md 伪代码使用不存在的 WithToken API
    • security-hardening.mdHOTPLEX_GATEWAY_TOKEN 替换语义需确认

合并后建议跟踪

  1. 添加 api_key_strength checker(最小长度/熵检查)
  2. 非 localhost + 无 API Key 时输出 WARN 日志
  3. 考虑 AuthenticateKey 使用 subtle.ConstantTimeCompare
  4. 文档强调生产环境必须 WSS
  5. 修复 QuickStart.java 变量命名和 integration-patterns 伪代码

Copy link
Copy Markdown
Owner

@hotplex-ai hotplex-ai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

三维度审查报告

代码质量: PASS (8.5/10)

  • DRY: JWT 相关代码清理彻底,无孤立引用
  • SOLID: 接口简化合理,耦合度降低
  • 命名/错误处理/代码风格均符合项目规范
  • ~100 文件的删除一致性良好

非功能性(安全+性能+并发): FAIL (安全 5.5/10)

FAIL 项(合并前必须解决):

  1. SEC-001 时序攻击风险auth.go:72 API Key 验证使用 map[string]bool 查找,非常量时间。旧代码的 subtle.ConstantTimeCompare 被移除且未替换。作为唯一认证门禁,应改为遍历 + subtle.ConstantTimeCompare

  2. SEC-003 Bot ID 伪造风险BotIDFromRequest 从未签名的 X-Bot-ID header / bot_id query param 提取 bot ID,客户端可设置任意值绕过多 bot 隔离。建议添加 API Key-to-BotID 绑定验证,或在安全文档中明确声明此信任边界。

  3. SEC-002 凭证生命周期 — 移除 JWT 后失去 token 过期/撤销机制,泄露的 API Key 永久有效。建议添加 per-key last-used 追踪 + 可选 TTL。

WARN 项(合并后尽快处理):

  • SEC-004: api_key query param 存在日志泄漏风险
  • SEC-005: RequireSecrets() 被删除,生产环境可能无 API Key 启动
  • SEC-006: Scopes/roles 被移除,所有 key 拥有相同权限
  • CONC-004: resolveUserID 在读锁下调用外部 resolver 可能阻塞

集成与防腐: FAIL

  1. security_fix_test.go 被删除fixAdminTokenwriteEnvVarunsetEnvVarfixEnvInGit 仍被 hotplex doctor --fix 使用,但失去了所有测试覆盖。需恢复测试。

WARN 项:

  • docs/security/Env-Whitelist-Strategy.mdHOTPLEX_GATEWAY_TOKEN 占位符未更新为实际变量名

总结:重构执行质量高(代码清理彻底),但安全模型从密码学强绑定(ES256 JWT)降级为静态共享密钥后,需补充恒定时间比较和 Bot ID 绑定验证来维持安全水位。

@hrygo hrygo requested a review from hotplex-ai May 22, 2026 05:02
hrygo pushed a commit that referenced this pull request May 22, 2026
- SEC-001: API Key 验证改用 subtle.ConstantTimeCompare 防止时序攻击
- SEC-003: BotIDFromRequest 添加信任边界文档注释
- CONC-004: AuthenticateRequest 将 resolver 调用移到读锁外
- 恢复 security_fix_test.go 测试覆盖(fixAdminToken/writeEnvVar/unsetEnvVar/fixEnvInGit)
- 移除 Env-Whitelist 文档中已废弃的 HOTPLEX_GATEWAY_TOKEN 引用
移除 ES256 JWT 签名认证体系(jwt.go、HKDF 密钥派生、JTI 黑名单),
替换为 X-API-Key + X-Bot-ID 双头认证模型。浏览器 WebSocket 客户端
通过 AEP init envelope 延迟传递认证信息。

Breaking changes:
- 删除 JWT 全部代码(internal/security/jwt.go, jwt_test.go)
- 删除 config SecretsProvider 管线(LoadOptions, EnvSecretsProvider)
- 删除 client SDK token 生成(client/token.go, gen-token, 08_token_generator)
- 删除 Java jjwt/bcprov 依赖
- BotIDFromHeader 重命名为 BotIDFromRequest

Migration: 设置 HOTPLEX_ADMIN_TOKEN_1 环境变量,
WebSocket 客户端通过 init envelope auth.token/auth.bot_id 传递凭证。

124 files changed, +857/-3815 lines
- QuickStart.java: signingKey → apiKey
- integration-patterns.md: Go SDK 用 client.APIKey()/client.BotID(),
  TS SDK 用 apiKey,Python SDK 用 api_key
- security-hardening.md: 合并重复的 Bot ID 审计项 (3&4→3)
- SEC-001: API Key 验证改用 subtle.ConstantTimeCompare 防止时序攻击
- SEC-003: BotIDFromRequest 添加信任边界文档注释
- CONC-004: AuthenticateRequest 将 resolver 调用移到读锁外
- 恢复 security_fix_test.go 测试覆盖(fixAdminToken/writeEnvVar/unsetEnvVar/fixEnvInGit)
- 移除 Env-Whitelist 文档中已废弃的 HOTPLEX_GATEWAY_TOKEN 引用
@hrygo hrygo force-pushed the refactor/467-remove-jwt-dependency branch from 4788864 to 42d94c6 Compare May 22, 2026 05:25
@hrygo hrygo merged commit 0528e3d into main May 22, 2026
6 checks passed
@hrygo hrygo deleted the refactor/467-remove-jwt-dependency branch May 22, 2026 05:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(security): simplify botID transport, remove JWT dependency for WS/REST clients

2 participants